package com.github.zj.dreamly.netty.nio;

import java.net.InetSocketAddress;
import java.nio.Buffer;
import java.nio.ByteBuffer;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.Arrays;

/**
 * Scattering：将数据写入到buffer时，可以采用buffer数组，依次写入  [分散]
 * Gathering: 从buffer读取数据时，可以采用buffer数组，依次读
 */
public class ScatteringAndGatheringTest {
	public static void main(String[] args) throws Exception {

		//使用 ServerSocketChannel 和 SocketChannel 网络

		ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
		InetSocketAddress inetSocketAddress = new InetSocketAddress(7000);

		//绑定端口到socket ，并启动
		serverSocketChannel.socket().bind(inetSocketAddress);

		//创建buffer数组
		ByteBuffer[] byteBuffers = new ByteBuffer[2];
		byteBuffers[0] = ByteBuffer.allocate(5);
		byteBuffers[1] = ByteBuffer.allocate(3);

		//等客户端连接(telnet)
		SocketChannel socketChannel = serverSocketChannel.accept();
		//假定从客户端接收8个字节
		int messageLength = 8;
		//循环的读取
		while (true) {

			int byteRead = 0;

			while (byteRead < messageLength) {
				long l = socketChannel.read(byteBuffers);
				//累计读取的字节数
				byteRead += l;
				System.out.println("byteRead=" + byteRead);
				//使用流打印, 看看当前的这个buffer的position 和 limit
				Arrays.stream(byteBuffers).map(buffer ->
					"postion=" + buffer.position() + ", limit="
						+ buffer.limit()).forEach(System.out::println);
			}

			//将所有的buffer进行flip
			Arrays.asList(byteBuffers).forEach(Buffer::flip);

			//将数据读出显示到客户端
			long byteWirte = 0;
			while (byteWirte < messageLength) {
				long l = socketChannel.write(byteBuffers);
				byteWirte += l;
			}

			//将所有的buffer 进行clear
			Arrays.asList(byteBuffers).forEach(Buffer::clear);

			System.out.println("byteRead:=" + byteRead + " byteWrite=" + byteWirte + ", messagelength" + messageLength);
		}
	}
}
